package com.kirk.cts.ui.view.panel;

import com.kirk.cts.core.loader.ImageLoader;
import com.kirk.cts.ui.style.GuiUtils;

import javax.swing.*;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;


@org.springframework.stereotype.Component("pageContainer")
public class PageContainer extends JPanel implements AncestorListener {


    static final int PREFERED_HEIGHT = 24;// 22

    /**
     * the titleControlPanel.
     */
    private JPanel titleControlPanel;

    /**
     * the pageContainer.
     */
    private JPanel pageContainer;

    /**
     * the titleLabel.
     */
    private JLabel titleLabel;

    /**
     * control toolBar
     */
    private JToolBar controlToolBar;

    /**
     * the previousPageButton.
     */
    private JButton previousPageButton;

    /**
     * the nextPageButton.
     */
    private JButton nextPageButton;

    /**
     * the closePageButton.
     */
    private JButton closePageButton;

    /**
     * the CardLayout for centerPane.
     */
    private CardLayout card;

    /**
     * the CardLayout for currentPage.
     */
    private IPage currentPage;

    /**
     * the CardLayout for centerPane.
     */
    private int currentPageIndex = 0;

    /**
     * the default panel.
     */
    private IPage defaultPage;

    private PageContainer() {
        super();

        // set Layout.
        this.setLayout(new BorderLayout());

        // add the titleControlPanel.
        this.add(getTitleControlPanel(), BorderLayout.NORTH);

        // add the CardCotentPanel.
        this.add(getPageContainer(), BorderLayout.CENTER);
    }


    /**
     * create titleControlPanel.
     *
     * @return titleControlPanel
     */
    public JPanel getTitleControlPanel2() {
        if (titleControlPanel == null) {
            // 创建内容面板容器
            titleControlPanel = new JPanel();
            // 设置大小
            titleControlPanel.setPreferredSize(new Dimension(0, 28));
            // 创建分组布局，并关联容器
            GroupLayout layout = new GroupLayout(titleControlPanel);
            // 设置容器的布局
            titleControlPanel.setLayout(layout);
            // 自动创建组件之间的间隙
            // layout.setAutoCreateGaps(true);
            // 自动创建容器与触到容器边框的组件之间的间隙
            // layout.setAutoCreateContainerGaps(true);

            /*
             * 水平组（仅确定 X 轴方向的坐标/排列方式）
             *
             * 水平串行: 水平排列（左右排列）
             * 水平并行: 垂直排列（上下排列）
             */
            // 指定布局的水平组（确定组件在 X轴 方向上的位置）
            layout.setHorizontalGroup(
                    // 创建 并行组 (上下对齐)
                    layout.createParallelGroup(GroupLayout.Alignment.CENTER).addGroup(
                            // 创建 串行组 （左右对齐）
                            layout.createSequentialGroup()
                                    // 添加 间隙
                                    .addContainerGap()
                                    // 添加 title标签组件元素
                                    .addComponent(getTitleLabel())
                                    // 设置title大小和位置
                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 156, Short.MAX_VALUE)
                                    // 添加控制工具栏组件
                                    .addComponent(getControlToolBar(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)));
            // 指定布局的垂直组（确定组件在 Y轴 方向上的位置）
            layout.setVerticalGroup(
                    // 创建 并行组(上下对齐)
                    layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(
                            // 创建 串行组 （左右对齐）
                            layout.createSequentialGroup().addGroup(
                                    // 创建 并行组
                                    layout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
                                            // 添加 title标签组件元素
                                            .addComponent(getTitleLabel())
                                            // 设置title大小和位置
                                            .addComponent(getControlToolBar(), GroupLayout.PREFERRED_SIZE, 25, GroupLayout.PREFERRED_SIZE))
                                    // 添加 间隙
                                    .addContainerGap()));
            titleControlPanel.setBorder(BorderFactory.createLineBorder(GuiUtils.getLookAndFeelColor("lineColor")));
        }
        return titleControlPanel;
    }

    /**
     * create titleControlPanel.
     *
     * @return titleControlPanel
     */
    public JPanel getTitleControlPanel() {
        if (titleControlPanel == null) {
            titleControlPanel = new JPanel();
            // 实例化网格布局对象
            GridBagLayout gridbag = new GridBagLayout();
            // 实例化这个对象用来对组件进行管理
            GridBagConstraints c = new GridBagConstraints();
            titleControlPanel.setLayout(gridbag);
            // centerPane.setBorder(BorderFactory.createLineBorder(Color.red));

            int top = 2;
            int left = 1;
            int bottom = 2;
            int right = 1;
            Insets inserts = new Insets(top, left, bottom, right);
            /** type. */
            // getTitleLabel()
            /**
             *  该方法是为了设置如果组件所在的区域比组件本身要大时的显示情况
             *  NONE：不调整组件大小。
             *  HORIZONTAL：加宽组件，使它在水平方向上填满其显示区域，但是不改变高度。
             *  VERTICAL：加高组件，使它在垂直方向上填满其显示区域，但是不改变宽度。
             *  BOTH：使组件完全填满其显示区域。
             */
            c.fill = GridBagConstraints.BOTH;

            c.weightx = 0.0;
            c.weighty = 0.0;
            c.insets = inserts;
            c.anchor = GridBagConstraints.LINE_START;
            // 组件1(gridx,gridy)组件的左上角坐标，
            c.gridx = 0;
            c.gridy = 0;
            // gridwidth，gridheight：组件占用的网格行数和列数
            c.gridwidth = 1;
            c.gridheight = 1;
            titleControlPanel.add(getTitleLabel(), c);

            // spaceLabel
            c.gridx = GridBagConstraints.RELATIVE;
            c.weightx = 1.0;
            titleControlPanel.add(new JLabel(), c);
            c.weightx = 0.0;

            titleControlPanel.add(getPreviousPageButton(), c);
            titleControlPanel.add(getNextPageButton(), c);
            titleControlPanel.add(getClosePageButton(), c);

        }
        return titleControlPanel;
    }

    /**
     * create centerPane.
     *
     * @return centerPane
     */
    public JPanel getPageContainer() {
        if (pageContainer == null) {
            pageContainer = new JPanel();

            if (card == null) {
                card = new CardLayout();
                pageContainer.setLayout(card);
            }
        }

        return pageContainer;
    }

    /**
     * @return titleLabel
     */
    private JLabel getTitleLabel() {
        if (titleLabel == null) {
            titleLabel = new JLabel();
            // test
            setTitleLabelText("Card Title");
            titleLabel.setBackground(Color.RED);
        }

        return titleLabel;
    }

    /**
     * set the title Label text.
     */
    public void setTitleLabelText(String title) {
        if (titleLabel != null && title != null) {
            titleLabel.setText(title);
            // titleLabel.validate();
        }
    }

    private JToolBar getControlToolBar() {
        if (controlToolBar == null) {
            controlToolBar = new JToolBar();
            controlToolBar.setFloatable(false);
            controlToolBar.add(getPreviousPageButton());
            controlToolBar.add(getNextPageButton());
            controlToolBar.add(getClosePageButton());
        }
        return controlToolBar;
    }

    /**
     * show previous card Label.
     */
    private JButton getPreviousPageButton() {
        if (previousPageButton == null) {
            previousPageButton = new JButton();
            previousPageButton.setEnabled(false);
            previousPageButton.setPreferredSize(new Dimension(24, 24));
            previousPageButton.setIcon(ImageLoader.getImageIcon("CrawlerResource.actionBack"));

            previousPageButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent event) {
                    showPrevious();
                }
            });
        }
        return previousPageButton;
    }

    /**
     * close card Button.
     */
    private JButton getNextPageButton() {
        if (nextPageButton == null) {
            nextPageButton = new JButton();
            nextPageButton.setPreferredSize(new Dimension(24, 24));
            nextPageButton.setIcon(ImageLoader.getImageIcon("CrawlerResource.actionForward"));
            nextPageButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent event) {
                    showNext();
                }
            });
        }
        return nextPageButton;
    }

    /**
     * close card Button.
     */
    private JButton getClosePageButton() {
        if (closePageButton == null) {
            closePageButton = new JButton();
            closePageButton.setPreferredSize(new Dimension(24, 24));
            closePageButton.setIcon(ImageLoader.getImageIcon("CrawlerResource.actionStop"));

            closePageButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent event) {
                    if (currentPage != null) {
                        removeCardPanel();
                    }
                }
            });
        }
        return closePageButton;
    }

    /**
     * show the first Container.
     */
    public void showFirst() {
        card.first(pageContainer);
        // update
        updateTitleControlPanel();
    }

    /**
     * show the next Container.
     */
    public void showNext() {
        card.next(pageContainer);
        // update
        updateTitleControlPanel();
    }

    /**
     * show the previous Container.
     */
    public void showPrevious() {
        card.previous(pageContainer);
        // update
        updateTitleControlPanel();
    }

    /**
     * show the last Container.
     */
    public void showLast() {
        card.last(pageContainer);
        // update
        updateTitleControlPanel();
    }

    public void show(String name) {
        card.show(pageContainer, name);
        // update
        updateTitleControlPanel();
    }

    public void show(Component comp, String name) {
    }

    public void isExist(Component comp) {
        // pageContainer.
    }

    private boolean isFirst() {
        return currentPageIndex == 0;
    }

    private boolean isLast() {
        return currentPageIndex == getPageCount() - 1;
    }

    private boolean isEmpty() {
        return getPageCount() == 0;
    }

    /**
     * Adds the specified Component to this card layout's internal table of
     * names.
     *
     * @see CardLayout#addLayoutComponent(Component,
     * Object)
     */
    public void addPage(Component comp, Object constraints) {
        getPageContainer().add(comp, constraints);
        show((String) constraints);
        // updateTitleControlPanel();
        // card.
        // updateTitleControlPanel();
    }

    /**
     * Removes the specified Component from the layout.
     *
     * @see CardLayout#removeLayoutComponent(Component)
     */
    public void removeCardPanel() {
        pageContainer.remove((Component) currentPage);
        card.removeLayoutComponent((Component) currentPage);

        // Dispose this card.
        currentPage.disposePage();
        currentPage = null;

        // update
        updateTitleControlPanel();
    }

    /**
     * @return an Array of all cardPanel in the pageContainer.
     */
    public Component[] getPages() {
        return pageContainer.getComponents();
    }

    /**
     * @return the number of cardPanel in the pageContainer.
     */
    public int getPageCount() {
        synchronized (pageContainer.getTreeLock()) {
            return pageContainer.getComponentCount();
        }
    }

    /**
     * @return the visible card and update the current Card index.
     */
    public IPage findCurrentPage() {
        Component visibleComp = null;

        synchronized (pageContainer.getTreeLock()) {
            int ncomponents = pageContainer.getComponentCount();
            for (int i = 0; i < ncomponents; i++) {
                Component comp = pageContainer.getComponent(i);
                if (comp.isVisible()) {
                    visibleComp = comp;
                    currentPageIndex = i;
                    break;
                }
            }
        }
        currentPage = (IPage) visibleComp;
        return (IPage) visibleComp;
    }

    private void updateTitleControlPanel() {
        // update the current card index.
        findCurrentPage();

        // set the control panel title.
        if (currentPage != null) {
            setTitleLabelText(currentPage.getPageName());
        } else {
            setTitleLabelText("Chang to Defautl title.");
            //currentPage is null return.
            return;
        }

        // if current card is the first card.
        if (isEmpty() || isFirst()) {
            previousPageButton.setEnabled(false);
        } else {
            previousPageButton.setEnabled(true);
        }

        // if current card is the last card.
        if (isEmpty() || isLast()) {
            nextPageButton.setEnabled(false);
        } else {
            nextPageButton.setEnabled(true);
        }

        if (currentPage.isDefaultPage()) {
            closePageButton.setEnabled(false);
        } else {
            closePageButton.setEnabled(true);
        }
    }

    public void setDefaultPage(IPage cardComponet) {
        if (cardComponet != null) {
            if (cardComponet instanceof Component) {
                defaultPage = cardComponet;
                defaultPage.setDefaultPage(true);
                addPage((Component) defaultPage, defaultPage.getPageId());
            }
        }
    }

    @Override
    public void ancestorAdded(AncestorEvent event) {
        // TODO Auto-generated method stub
        // findCurrentCard();
    }

    @Override
    public void ancestorMoved(AncestorEvent event) {
        // TODO Auto-generated method stub

    }

    @Override
    public void ancestorRemoved(AncestorEvent event) {
        // TODO Auto-generated method stub

    }
}
